using System.Data.Common;

namespace SeataNet.Core.AT
{
    /// <summary>
    /// 数据源接口
    ///
    /// 定义创建数据库连接的标准接口，类似JDBC的DataSource接口。
    ///
    /// 职责：
    /// - 提供统一的数据库连接创建方法
    /// - 作为AtDataSourceProxy和其他数据源实现的基接口
    /// - 抽象数据库连接的创建逻辑
    ///
    /// 工作原理：
    /// ```
    /// 应用层
    ///    ↓
    /// IDataSource接口
    ///    ↓
    /// 实现类（AtDataSourceProxy、HikariDataSource等）
    ///    ↓
    /// DbConnection（真实数据库连接）
    /// ```
    ///
    /// 实现类：
    /// - AtDataSourceProxy：AT模式数据源代理，支持分布式事务
    /// - 其他自定义数据源：可以实现此接口提供连接池等功能
    ///
    /// 使用场景：
    /// ```csharp
    /// // 场景1：使用AT模式数据源
    /// IDataSource dataSource = new AtDataSourceProxy(...);
    /// using (var connection = dataSource.CreateConnection())
    /// {
    ///     await connection.OpenAsync();
    ///     // 执行SQL
    /// }
    ///
    /// // 场景2：依赖注入
    /// services.AddSingleton<IDataSource, AtDataSourceProxy>();
    ///
    /// public class OrderRepository
    /// {
    ///     private readonly IDataSource _dataSource;
    ///
    ///     public OrderRepository(IDataSource dataSource)
    ///     {
    ///         _dataSource = dataSource;
    ///     }
    ///
    ///     public async Task CreateOrderAsync(Order order)
    ///     {
    ///         using (var connection = _dataSource.CreateConnection())
    ///         {
    ///             // ...
    ///         }
    ///     }
    /// }
    ///
    /// // 场景3：自定义实现（带连接池）
    /// public class PooledDataSource : IDataSource
    /// {
    ///     private readonly ConcurrentBag<DbConnection> _pool;
    ///
    ///     public DbConnection CreateConnection()
    ///     {
    ///         if (_pool.TryTake(out var connection))
    ///         {
    ///             return connection;  // 复用连接
    ///         }
    ///         return CreateNewConnection();  // 创建新连接
    ///     }
    /// }
    /// ```
    ///
    /// 与JDBC DataSource的对比：
    /// - JDBC DataSource：Java中的标准数据源接口
    /// - IDataSource：.NET中的简化版本
    /// - 相同点：都提供CreateConnection()方法
    /// - 不同点：.NET使用DbConnection而非Connection
    ///
    /// 设计模式：
    /// - 工厂模式：CreateConnection()是工厂方法
    /// - 代理模式：AtDataSourceProxy实现此接口并代理底层连接
    /// - 接口隔离原则：只定义必要的方法，保持接口简洁
    ///
    /// 注意事项：
    /// - 创建的连接需要调用方负责关闭和释放
    /// - 实现类应该是线程安全的（支持并发调用）
    /// - 连接池实现应该在实现类中处理
    /// - 不负责连接的生命周期管理（由调用方管理）
    /// </summary>
    public interface IDataSource
    {
        /// <summary>
        /// 创建数据库连接
        ///
        /// 创建并返回一个新的数据库连接对象（DbConnection）。
        ///
        /// 执行流程：
        /// 1. 实现类根据配置创建底层DbConnection
        /// 2. 如果是代理模式（如AtDataSourceProxy），包装为代理连接
        /// 3. 返回连接对象
        ///
        /// 调用时机：
        /// - 应用需要访问数据库时
        /// - 通常在业务方法开始时调用
        /// - 使用using语句确保连接正确释放
        ///
        /// 使用示例：
        /// ```csharp
        /// // 示例1：基本用法
        /// using (var connection = dataSource.CreateConnection())
        /// {
        ///     await connection.OpenAsync();
        ///     using (var command = connection.CreateCommand())
        ///     {
        ///         command.CommandText = "SELECT * FROM orders WHERE id = @id";
        ///         command.Parameters.Add(new DbParameter { ParameterName = "@id", Value = 1001 });
        ///         using (var reader = await command.ExecuteReaderAsync())
        ///         {
        ///             // 处理结果
        ///         }
        ///     }
        /// }
        ///
        /// // 示例2：AT模式下的使用
        /// using (var connection = atDataSource.CreateConnection())  // 返回AtConnectionProxy
        /// {
        ///     await connection.OpenAsync();
        ///     // 执行SQL，自动生成undo_log
        ///     await connection.ExecuteNonQueryAsync("UPDATE account SET balance = balance - 100 WHERE id = 1");
        ///     // 提交时自动注册分支事务
        /// }
        ///
        /// // 示例3：在Repository中使用
        /// public class OrderRepository
        /// {
        ///     private readonly IDataSource _dataSource;
        ///
        ///     public async Task<Order> GetOrderByIdAsync(long id)
        ///     {
        ///         using (var connection = _dataSource.CreateConnection())
        ///         {
        ///             await connection.OpenAsync();
        ///             // 查询订单
        ///             return await QueryOrderAsync(connection, id);
        ///         }
        ///     }
        /// }
        /// ```
        ///
        /// 返回值说明：
        /// - 返回DbConnection对象（可能是代理对象）
        /// - 连接未打开，需要调用OpenAsync()
        /// - 调用方负责关闭连接（使用using或手动Close）
        ///
        /// 注意事项：
        /// - 创建的连接未打开，需要调用OpenAsync()
        /// - 必须使用using或手动Close释放连接
        /// - 如果是AtDataSourceProxy，返回的是AtConnectionProxy代理对象
        /// - 连接可能来自连接池（取决于实现类）
        /// - 方法应该是线程安全的（可以并发调用）
        /// - 创建失败可能抛出异常（如数据库不可用）
        /// </summary>
        /// <returns>数据库连接对象（DbConnection或其子类/代理类）</returns>
        /// <exception cref="Exception">创建连接失败时可能抛出异常（取决于实现类）</exception>
        DbConnection CreateConnection();
    }
}
